import UIKit

//String是有序的Character类型的值的集合。通过String类型来表示
//字符串字面量 是由双引号""包裹的具体固定顺序的文本字符集 可以为常量或变量提供初始值
let someString = "Some string iteral value"
//可以包含以下特殊字符
//转义字符：\0-空字符 \\反斜杠 \t制表符 \n换行符 \r回车 \"双引号 \'单引号
//Unicode标量。写成\u{n},n为任意的一到八位十六进制数。
let wiseWord = "\"我是要成为海蜇王的男人\" - 路飞"
let dollarSign = "\u{24}" //"$" Unicode的标量是U+0024
let blackHeart = "\u{2665}" //"♥"
let sparklingHeart = "\u{1F496}"//"💖"
//初始化空字符串
var emptyString = ""
var anotherString = String()
if emptyString.isEmpty {
    print("什么都没有")
}

//字符串的可变性 let 不可变字符串 var 可变字符串
var variableString = "horse"
variableString = " and carriage" //可变OK
let contantString = "Highlander"
//contantString += " and another Highlander" //不可变 wrong
//在OC中你选择NSString和NSMutableString来指定字符串是否可以被修改，而在Swift中是否可以修改仅通过定义的是变量和常量即可。
//字符串是值类型。如果你创建了一个新字符串，那么当其机进行常量，变量赋值操作或者在函数方法中传递时，会进行值拷贝。任何情况下都会对已有字符串创建新副本。并对该新副本进行传递或赋值操作。注意这点与OC的NSString实例是不一样的，OC的NSString是引用。Swift默认字符串拷贝的方式保证了函数，方法中传递是字符串的值。很明显无论来自哪里，都是您独自拥有的。您可以放心传递，字符串本身不会修改。
//使用字符Character，每个Character代表一个Unicode字符。通过for-in循环来遍历字符串的每个字符
for character in "Dog!" {
    print(character)
}
//通过表明一个character类型注解并通过字符字面量进行赋值，可以建立一个独立的字常量或变量
let yenSign: Character = "💵"
print(yenSign)
//计算字符数量 countElements
let unusualManagerie = "Koal 🐶， Snial 🐍"
print("unusualManagerie has \(unusualManagerie.underestimatedCount) characters.")
//连接字符串和字符 通过 +
let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
//也可以通过加法赋值运算 += 将一个字符串添加到一个已存在的字符串变量上
var instruction = "look over"
instruction += string2
//通过append方法将一个字符附加到一个字符串变量的尾部
let exclamationMark = "!"
welcome.append(exclamationMark)
//字符串插值 是一种构建新字符串的方式。可以在其中包含常量、变量、字面量和表达式。你插入的字符串字面量的每一项都被包裹在以反斜杠为前缀的元口中。
let multiplier = 3
let message = "\(multiplier) 乘以 2.5是 \(Double(multiplier) * 2.5)"

//比较字符串
//相等
let quotation = "我们是一样一样的"
let sameQuotation = "我们是一样一样的"
if quotation == sameQuotation {
    print("这两个字符串被认为相同的")
}

//前缀、后缀相等,通过hasPrefix/hasSuffix
let remeoAndJuliet = [
    "Act1 Scene 1: Verona, A public place",
    "Act1 Scene 2: Capulet's mansion",
    "Act2 Scene 1: Capulet's mansion",
    "Act2 Scene 2: Capulet's mansion",
]
var act1SceneCount = 0
for sce in remeoAndJuliet {
    if sce.hasPrefix("Act1") {
        act1SceneCount += 1
    }
}

var mansionCount = 0
var cellCount = 0
for scene in remeoAndJuliet {
    if scene.hasSuffix("Capulet's mansion") {
        mansionCount += 1
    } else if scene.hasSuffix("Friar Lawence's cell") {
        cellCount += 1
    }
}
//大小写
let normal = "Could you help me, please?"
let shouty = normal.uppercased()
let shispered = normal.lowercased()

//Unicode 是一个国际标准，用于文本的编码和显示。当Unicode字符串被写入文本文件或者其他存储结构中，这些unicode标量会按照Unicode定义的集中格式之一进行编码，包括UTF-8(以8位代码单元进行编码)和UTF-16(以16位代码单元进行编码)
//字符串的Unicode表示

//UTF-8，你可以遍历字符串的utf8属性来访问它的UTF-8表示。
let dogString = "Dog!🐶"
for codeUnit in dogString.utf8 {
    print("\(codeUnit)") //68 111 103 33 代表了字符D o g  !,他们的utf8表示与ASCII相同。后面四个240 159 144 182是DOG FACE的4字节UTF-8表示。
}

//UTF-16 你可以遍历字符串的utf16属性来访问它的UTF-8表示,同样的，前四个68 111 103 33 代表了字符D o g  !,他们的UTF16和UTF-8完全相同，第五和第六个代码单元值55357
// 56374是DOG FACE的4字节UTF-16表示，第一个值为U+D83D(十进制是55357)第二个是U+DC36(十进制是56374)
for codeUnit in dogString.utf16 {
    print("\(codeUnit)")
}
//Unicode的标量 unicodeSclar是21位的Unicode代码点。
for sclar in dogString.unicodeScalars {
    print("\(sclar.value)")
    print("\(sclar)") //每个unicodescalar值也可以用来构建一个新的字符串值。
}

